package com.zxjbyte.yiyi.module.upms.controller.auth;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import com.zxjbyte.yiyi.framework.common.constant.Constant;
import com.zxjbyte.yiyi.framework.common.constant.StatusConstant;
import com.zxjbyte.yiyi.framework.common.domain.api.R;
import com.zxjbyte.yiyi.module.upms.domain.vo.CaptchaVO;
import com.zxjbyte.yiyi.module.upms.service.CaptchaService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * 基于hutool实现的验证码接口
 *
 * @Author zhangxingjia
 * @Date 2024/8/13 17:03
 * @Version: 1.0
 */
@Slf4j
@Tag(name = "验证码接口")
@RestController
@RequestMapping(value = "/upms/captcha")
public class CaptchaController {

    @Resource
    private CaptchaService captchaService;
    @Value("${yiyi.captcha.secret-key}")
    private String secretKey;

    @Operation(summary = "生成验证码")
    @GetMapping("/generate")
    public R<CaptchaVO> generateCaptcha(@RequestParam String timestamp, @RequestParam String signature) {
        // 验证码接口一般不需要鉴权，接口HMAC签名验证，防止被恶意攻击
        if(!verifySignature(timestamp, signature)){
            return R.fail("Invalid signature");
        }
        return R.data(captchaService.generateCaptcha());
    }

    @Operation(summary = "验证验证码")
    @GetMapping("/verify")
    public R<?> verify(@RequestParam String uuid, @RequestParam String code) {
        int verifyResult = captchaService.verify(uuid, code);
        if (verifyResult == StatusConstant.EXPIRE) {
            return R.fail("验证已过期，请重新获取");
        } else if (verifyResult == StatusConstant.FAIL) {
            return R.fail("验证码验证错误");
        }
        return R.ok();
    }

    /**
     * 验证 HMAC 签名
     */
    private boolean verifySignature(String timestamp, String clientSignature) {
        try {
            // 服务端生成签名
            HMac hmac = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, secretKey.getBytes(Constant.CHARSET_UTF_8));
            String serverSignature = hmac.digestBase64(timestamp, true);
            return serverSignature.equals(clientSignature);
        } catch (Exception e) {
            return false;
        }
    }

}
